<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="">
    <meta name="author" content="">

    <title>Three.js Helpers</title>
    
    <style type="text/css">
      html { overflow: hidden; }
      body { margin: 0; padding: 0; overflow: hidden; font-family: Monospace; font-size: 13px; line-height: 20px; color: #333; }

      a { color: #0088cc; text-decoration: none; }
      a:hover, a:focus { color: #005580; text-decoration: underline; }
    </style>

  </head>

  <body>

    <div id="container"></div>
    
    <script src="three/three.min.js"></script>
    <script src="three/OrbitControls.js"></script>
    <script src="three/WebGL.js"></script>
    <script src="three/libs/dat.gui.min.js"></script>
    <script src="three/libs/tween.min.js"></script>
    <script src="three/geometries/TeapotBufferGeometry.js"></script>

    <script>

      if ( !WEBGL.isWebGLAvailable() ) {
        document.body.appendChild( WEBGL.getWebGLErrorMessage() );
      }

      var container;

      var camera, controls, scene, renderer;

      var mesh;

      var wfh, grid, box, bbox, axes, fnh, vnh;

      var keyLightHelper, fillLightHelper, rimLightHelper;

      var mouseX = 0, mouseY = 0;

      var clock = new THREE.Clock();

      var windowHalfX = window.innerWidth / 2;
      var windowHalfY = window.innerHeight / 2;

      init();
      animate();

      function init() {

        container = document.getElementById( 'container' );

        camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 100000 );
        camera.position.set( 0, 200, 300 );

        scene = new THREE.Scene();



        // ambient light
        ambLight = new THREE.AmbientLight( 0x444444 );
        scene.add( ambLight );


        // directional - KEY LIGHT
        keyLight = new THREE.DirectionalLight( 0xdddddd, .7 );
        keyLight.position.set( -80, 60, 80 ).multiplyScalar(1.4);
        scene.add( keyLight );
        
        keyLightHelper = new THREE.DirectionalLightHelper( keyLight, 15 );
        keyLightHelper.visible = false;
        scene.add( keyLightHelper );


        // directional - FILL LIGHT
        fillLight = new THREE.SpotLight( 0x034df6, .8, 0, Math.PI/8, 0.01 );
        fillLight.position.set( 80, 80, 40 ).multiplyScalar(1.6);
        scene.add( fillLight );
        
        fillLightHelper = new THREE.SpotLightHelper( fillLight, 15 );
        fillLightHelper.visible = false;
        scene.add( fillLightHelper );


        // directional - RIM LIGHT
        rimLight = new THREE.PointLight( 0x00900a, .6 );
        rimLight.position.set( -20, 80, -80 ).multiplyScalar(1.4);
        scene.add( rimLight );
        
        rimLightHelper = new THREE.PointLightHelper( rimLight, 15 );
        rimLightHelper.visible = false;
        scene.add( rimLightHelper );



        // add objects here


        grid = new THREE.GridHelper( 350, 14 );
        grid.position.y = -30;
        grid.visible = false;
        scene.add( grid );

        
        // var material = new THREE.MeshBasicMaterial({ color: 0xffffff, transparent: true, opacity: 0.8 });

        // var material = new THREE.MeshBasicMaterial({ color: 0x333333, wireframe: true });
        var material = new THREE.MeshPhongMaterial({ color: 0xeeeeee, side: THREE.DoubleSide });

        var geometry = new THREE.TeapotBufferGeometry(16);

        mesh = new THREE.Mesh( geometry, material );
        mesh.scale.set(4,4,4);
        mesh.position.y = 30;
        scene.add( mesh );

        var wireframe = new THREE.WireframeGeometry( geometry );
        wfh = new THREE.LineSegments( wireframe );
        wfh.material.color.setHex(0x333333);
        wfh.visible = false;
        mesh.add( wfh );

        // world aligned bounding boxes
        box = new THREE.BoxHelper( mesh );
        box.material.color.setHex( 0xee6a00 );
        box.visible = false;
        scene.add( box );

        axes = new THREE.AxesHelper( 40 );
        // mesh.add( axes );

        // fnh = new THREE.FaceNormalsHelper( mesh, 10, 0xff0000 );
        // fnh.visible = false;
        // scene.add( fnh );

        vnh = new THREE.VertexNormalsHelper( mesh, 10, 0x0060ff );
        vnh.visible = false;
        scene.add( vnh );



        renderer = new THREE.WebGLRenderer( { antialias: true, alpha: true } );
        // renderer.setClearColor( 0xBBBBBB, 1 );
        renderer.setClearColor( 0x000000, 0 ); // the default
        renderer.setSize( window.innerWidth, window.innerHeight );

        container.appendChild( renderer.domElement );


        controls = new THREE.OrbitControls( camera, renderer.domElement );
        // controls.autoRotate = true;
        // controls.autoRotateSpeed = 2;
        controls.enableKeys = false;

        // document.addEventListener( 'mousemove', onDocumentMouseMove, false );

        //

        window.addEventListener( 'resize', onWindowResize, false );

      }


      function setupGui() {
        // dat.GUI debugging -----------------------------------------
        var gui = new dat.GUI();
        var f1 = gui.addFolder('meshOuter rotation');
        f1.add(mesh.position, 'x', 0, 2*Math.PI);
        f1.add(mesh.position, 'y', 0, 2*Math.PI);
        f1.add(mesh.position, 'z', 0, 2*Math.PI);
        f1.open();
      }


      function onWindowResize() {

        windowHalfX = window.innerWidth / 2;
        windowHalfY = window.innerHeight / 2;

        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();

        renderer.setSize( window.innerWidth, window.innerHeight );

      }

      function onDocumentMouseMove( event ) {

        mouseX = ( event.clientX - windowHalfX );
        mouseY = ( event.clientY - windowHalfY );

      }

      //

      function animate() {
        requestAnimationFrame( animate );

        render();
        controls.update();
        TWEEN.update();
      }

      function render() {

        var delta = clock.getDelta();

        if (mesh) {
          mesh.rotation.y -= 0.5 * delta;
          box.update();
          // fnh.update();
          vnh.update();
        }

        renderer.render( scene, camera );
      }



      function setupTween(obj, prop, targetValue) {
        var update  = function(){
          obj[prop] = current.property;
        }
        
        var current = { property: obj[prop] };
        var target = { property: targetValue };

        var tween = new TWEEN.Tween(current).to(target, 800)
          .easing(TWEEN.Easing.Cubic.Out)
          .onUpdate(update);

        tween.start();
      }

      var step = 1;

      function applyStep(step) {
        // console.log(step);
        if      (step == 1) {
          wfh.visible = false;
          grid.visible = false;
          box.visible = false;
          vnh.visible = false;
          keyLightHelper.visible = false;
          fillLightHelper.visible = false;
          rimLightHelper.visible = false;
        }
        else if (step == 2) {
          wfh.visible = true;
          grid.visible = false;
          box.visible = false;
          vnh.visible = false;
          keyLightHelper.visible = false;
          fillLightHelper.visible = false;
          rimLightHelper.visible = false;
        }
        else if (step == 3) {
          wfh.visible = false;
          grid.visible = true;
          box.visible = false;
          vnh.visible = false;
          keyLightHelper.visible = false;
          fillLightHelper.visible = false;
          rimLightHelper.visible = false;
        }
        else if (step == 4) {
          wfh.visible = false;
          grid.visible = false;
          box.visible = false;
          mesh.remove( axes );
          vnh.visible = false;
          keyLightHelper.visible = true;
          fillLightHelper.visible = true;
          rimLightHelper.visible = true;
        }
        else if (step == 5) {
          wfh.visible = false;
          grid.visible = false;
          box.visible = false;
          mesh.add( axes );
          vnh.visible = false;
          keyLightHelper.visible = false;
          fillLightHelper.visible = false;
          rimLightHelper.visible = false;
        }
        else if (step == 6) {
          wfh.visible = false;
          grid.visible = false;
          box.visible = true;
          mesh.remove( axes );
          vnh.visible = false;
          keyLightHelper.visible = false;
          fillLightHelper.visible = false;
          rimLightHelper.visible = false;
        }
        // else if (step == 7) {
        //   wfh.visible = false;
        //   grid.visible = false;
        //   box.visible = false;
        //   vnh.visible = true;
        //   keyLightHelper.visible = false;
        //   fillLightHelper.visible = false;
        //   rimLightHelper.visible = false;
        // }
      }

      onmessage = function(e) {
        step = e.data.director.args[0];
        applyStep( step );
      };

      function forward() {
        step++;
        if (step > 6) { step = 6; return; }
        applyStep(step);
      }

      function back() {
        step--;
        if (step <= 0) { step = 1; return; }
        applyStep(step);
      }

      // Controls for stand-alone
      window.addEventListener('keydown', function (e) {
        if (e.keyCode == 38 || e.keyCode == 37) back();
        if (e.keyCode == 40 || e.keyCode == 39) forward();
      });

    </script>

  </body>
</html>
